﻿using System;
using System.Collections.Generic;
using System.Configuration.Install;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using gc.utility.DosCommand;
using System.ServiceProcess;
using System.Diagnostics;

namespace gc.utility.WindowsService
{
    /// <summary>
    /// windows服务帮助类
    /// </summary>
    public static class WinServiceHelper
    {
        /// <summary>
        /// 安装服务
        /// </summary>
        /// <param name="serviceFileName">windows服务安装的exe完整路径</param>
        public static void Install(string serviceFileName)
        {
            string[] cmdline = { };
            TransactedInstaller transactedInstaller = new TransactedInstaller();
            AssemblyInstaller assemblyInstaller = new AssemblyInstaller(serviceFileName, cmdline);
            transactedInstaller.Installers.Add(assemblyInstaller);
            transactedInstaller.Install(new System.Collections.Hashtable());
        }

        /// <summary>
        /// 卸载服务
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>

        public static bool UnInstall(string serviceName)
        {
            Cmd.Execute("net stop " + serviceName);
            string result = Cmd.Execute("sc delete " + serviceName);

            if (result.Contains("DeleteService"))
                return true;
            else
                return false;
        }

        /// <summary>
        /// 获取所有的windows服务
        /// </summary>
        /// <returns></returns>

        public static ServiceController[] GetAllService()
        {
            return ServiceController.GetServices();
        }

        /// <summary>
        /// 获取指定的服务
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>

        public static ServiceController GetService(string serviceName)
        {
            if (serviceName.IsNullOrWhiteSpace())
                throw new ArgumentNullException("serviceName", "GetService method's Argument:serviceName must not null!");
            return new ServiceController(serviceName);
        }

        /// <summary>
        /// 根据一组服务名称获取服务列表
        /// </summary>
        /// <param name="serviceNames"></param>
        /// <returns></returns>
        public static List<ServiceController> GetService(IEnumerable<string> serviceNames)
        {
            if (serviceNames == null || !serviceNames.Any())
                return new List<ServiceController>();

            var s = GetAllService();

            return s.Where(r => serviceNames.Contains(r.ServiceName)).ToList();
        }

        /// <summary>
        /// 获取服务的状态
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static ServiceControllerStatus GetStatus(string serviceName)
        {
            var s = GetService(serviceName);

            var status = s.Status;

            s.Close();
            return status;
        }

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="serviceName"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static bool Start(string serviceName, params string[] args)
        {
            try
            {
                var s = GetService(serviceName);
                if (s.Status == ServiceControllerStatus.Running)
                    return true;

                if (args == null || args.Length == 0)
                    s.Start();
                else
                    s.Start(args);

                s.Close();
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static bool Stop(string serviceName)
        {
            try
            {
                var s = GetService(serviceName);

                if (s.CanStop)
                    s.Stop();
                s.Close();
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 暂停服务
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static bool Pause(string serviceName)
        {
            try
            {
                var s = GetService(serviceName);

                if (s.CanPauseAndContinue)
                    s.Pause();
                s.Close();
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 继续服务
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static bool Continue(string serviceName)
        {
            try
            {
                var s = GetService(serviceName);

                if (s.CanPauseAndContinue)
                    s.Continue();
                s.Close();
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 服务设为自动启动
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static bool SetAuto(string serviceName)
        {
            if (serviceName.IsNullOrWhiteSpace())
                throw new ArgumentNullException("serviceName");

            string result = Cmd.Execute(string.Format("sc config {0} start= auto", serviceName));

            if (result.Contains("ChangeServiceConfig"))
                return true;
            return false;
        }

        /// <summary>
        /// 服务设为禁用
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static bool SetDisabled(string serviceName)
        {
            if (serviceName.IsNullOrWhiteSpace())
                throw new ArgumentNullException("serviceName");

            string result = Cmd.Execute(string.Format("sc config {0} start= disabled", serviceName));

            if (result.Contains("ChangeServiceConfig"))
                return true;
            return false;
        }

        /// <summary>
        /// 服务设为手动
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static bool SetDemand(string serviceName)
        {
            if (serviceName.IsNullOrWhiteSpace())
                throw new ArgumentNullException("serviceName");

            string result = Cmd.Execute(string.Format("sc config {0} start= demand", serviceName));

            if (result.Contains("ChangeServiceConfig"))
                return true;
            return false;
        }

        /// <summary>
        /// 重启服务
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static bool Restart(string serviceName)
        {
            Stop(serviceName);
            return Start(serviceName);
        }

        public static bool IsExists(string serviceName)
        {
            string result = Cmd.Execute("sc query " + serviceName);
            return result.Contains(serviceName);
        }
    }
}
